﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.Dto;
using Happy.Dto.CommonModel.TreeLike;
using Happy.Domain;
using Happy.Domain.CommonModel.TreeLike;

namespace Happy.Application.Domain.CommonModel.TreeLike
{
    /// <summary>
    /// 树形结构服务。
    /// </summary>
    public abstract class TreeNodeService<TNode, TViewModel, TId, TUnitOfWork, TNodePathRepairer, TMoveNodeService>
        : AggregateRootService<TNode, TViewModel, TId, TUnitOfWork>
        where TNode : TreeNode<TId>
        where TViewModel : ITreeNodeView<TId>, IId<TId>, IOptimisticKey
        where TId : struct
        where TUnitOfWork : IUnitOfWork
        where TNodePathRepairer : INodePathRepairer
        where TMoveNodeService : MoveNodeService<TNodePathRepairer>
    {
        /// <inheritdoc />
        protected override TNode CreateAggregate(TViewModel viewModel)
        {
            if (viewModel.ParentId.HasValue)
            {
                var parent = this.LoadAggregate(viewModel.ParentId.Value);
                return this.NewAggregate(viewModel, parent);
            }

            return this.NewAggregate(viewModel);
        }

        /// <summary>
        /// 创建聚合根。
        /// </summary>c
        protected abstract TNode NewAggregate(TViewModel viewModel, TNode parent);

        /// <summary>
        /// 创建聚合根。
        /// </summary>c
        protected abstract TNode NewAggregate(TViewModel viewModel);

        /// <inheritdoc />
        protected override void UpdateAggregate(TNode aggregate, TViewModel viewModel)
        {
            this.Service<TMoveNodeService>()
                .MoveNodeTo<TNode, TId>(aggregate, viewModel.ParentId);
        }

        /// <inheritdoc />
        protected override void DeleteAggregate(TNode aggregate)
        {
            base.DeleteAggregate(aggregate);

            this.Service<TNodePathRepairer>().DeleteDescendants<TNode>(aggregate.NodePath);
        }
    }

    /// <summary>
    /// 树形结构服务。
    /// </summary>
    public abstract class TreeNodeService<TNode, TViewModel, TId, TUnitOfWork, TNodePathRepairer>
        : TreeNodeService<TNode, TViewModel, TId, TUnitOfWork, TNodePathRepairer, MoveNodeService<TNodePathRepairer>>
        where TNode : TreeNode<TId>
        where TViewModel : ITreeNodeView<TId>, IId<TId>, IOptimisticKey
        where TId : struct
        where TUnitOfWork : IUnitOfWork
        where TNodePathRepairer : INodePathRepairer
    {
    }

    /// <summary>
    /// 树形结构服务。
    /// </summary>
    public abstract class TreeNodeService<TNode, TViewModel, TUnitOfWork, TNodePathRepairer>
        : TreeNodeService<TNode, TViewModel, Guid, TUnitOfWork, TNodePathRepairer>
        where TNode : TreeNode<Guid>
        where TViewModel : ITreeNodeView<Guid>, IId<Guid>, IOptimisticKey
        where TUnitOfWork : IUnitOfWork
        where TNodePathRepairer : INodePathRepairer
    {
    }
}
